<template>
  <div class="workflow-edit">
    <div class="detail-header">
      <div class="header-left">
        <el-button link class="back-button" @click="router.back()">
          <el-icon><Back /></el-icon>
        </el-button>
        <h2 class="title">{{ isEdit ? '编辑工作流' : '创建工作流' }}</h2>
      </div>
      <div class="header-right">
        <el-button @click="router.back()">
          <el-icon><Close /></el-icon>
          <span>取消</span>
        </el-button>
        <el-button type="primary" @click="handleSave">
          <el-icon><Check /></el-icon>
          <span>保存</span>
        </el-button>
      </div>
    </div>

    <div class="content-wrapper" v-loading="loading">
      <h2 class="section-title">基本信息</h2>
      <el-form ref="formRef" :model="workflowForm" :rules="rules" label-width="100px">
        <el-form-item label="工作流名称" prop="name">
          <el-input v-model="workflowForm.name" placeholder="请输入工作流名称" />
        </el-form-item>
        <el-form-item label="作者" prop="author">
          <el-input v-model="workflowForm.author" placeholder="请输入作者">
            <template #prefix>
              <el-icon><User /></el-icon>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item label="标签" prop="label">
          <el-select
            ref="selectRef"
            v-model="workflowForm.label"
            multiple
            filterable
            allow-create
            default-first-option
            placeholder="请选择或创建标签"
            @select="handleTagSelect"
          >
            <el-option v-for="tag in availableTags" :key="tag" :label="tag" :value="tag" />
          </el-select>
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input
            v-model="workflowForm.description"
            type="textarea"
            :rows="3"
            placeholder="请输入工作流描述"
          />
        </el-form-item>
      </el-form>

      <!-- 章节编辑区域 -->
      <div class="chapters-editor">
        <div class="editor-layout">
          <!-- 左侧脚本列表 -->
          <div class="scripts-panel">
            <div class="panel-header">
              <h3>组件库</h3>
              <el-tabs v-model="activeTab" class="component-tabs">
                <el-tab-pane label="章节模板" name="chapters">
                  <div class="chapter-templates">
                    <div
                      class="chapter-template"
                      v-for="template in chapterTemplates"
                      :key="template.type"
                    >
                      <draggable
                        :list="[template]"
                        :group="{ name: 'chapters', pull: 'clone', put: false }"
                        :sort="false"
                        :clone="cloneChapter"
                        item-key="type"
                      >
                        <template #item="{ element: tmpl }">
                          <div class="template-content">
                            <el-icon><Files /></el-icon>
                            <span>{{ tmpl.name }}</span>
                          </div>
                        </template>
                      </draggable>
                    </div>
                  </div>
                </el-tab-pane>
                <el-tab-pane label="可用脚本" name="scripts">
                  <el-input
                    v-model="scriptSearchQuery"
                    placeholder="搜索脚本"
                    clearable
                    class="search-input"
                  >
                    <template #prefix>
                      <el-icon><Search /></el-icon>
                    </template>
                  </el-input>
                  <div class="script-list">
                    <draggable
                      :list="filteredScripts"
                      :group="{ name: 'scripts', pull: 'clone', put: false }"
                      item-key="ID"
                      :sort="false"
                      :clone="cloneScript"
                    >
                      <template #item="{ element: script }">
                        <div class="script-item available-script">
                          <el-icon><Document /></el-icon>
                          <span class="script-name">{{ script.name }}</span>
                          <el-tooltip
                            v-if="script.description"
                            :content="script.description"
                            placement="right"
                          >
                            <el-icon><InfoFilled /></el-icon>
                          </el-tooltip>
                        </div>
                      </template>
                    </draggable>
                  </div>
                </el-tab-pane>
              </el-tabs>
            </div>
          </div>

          <!-- 右侧章节区域 -->
          <div class="chapters-panel">
            <div class="panel-header">
              <h3>工作流章节</h3>
            </div>

            <el-scrollbar height="calc(100vh - 450px)">
              <draggable
                v-model="workflowForm.chapters"
                group="chapters"
                item-key="cid"
                handle=".chapter-drag-handle"
                ghost-class="ghost"
                :animation="200"
                @add="handleChapterAdd"
                @end="handleChapterDragEnd"
              >
                <template #item="{ element: chapter, index }">
                  <div class="chapter-item">
                    <div class="chapter-number">{{ index + 1 }}</div>
                    <div class="chapter-header">
                      <el-icon class="chapter-drag-handle"><Rank /></el-icon>
                      <el-input
                        v-model="chapter.name"
                        placeholder="章节名称"
                        class="chapter-name-input"
                      />
                      <el-tag size="small" type="info"> {{ chapter.tags.length }} 个脚本 </el-tag>
                      <el-button type="danger" link @click="removeChapter(index)">
                        <el-icon><Delete /></el-icon>
                      </el-button>
                    </div>

                    <div class="script-container">
                      <draggable
                        v-model="chapter.tags"
                        group="scripts"
                        item-key="tid"
                        handle=".script-drag-handle"
                        ghost-class="ghost"
                        :animation="200"
                        @add="handleScriptAdd($event, chapter)"
                        @end="handleScriptDragEnd($event, chapter)"
                      >
                        <template #item="{ element: script }">
                          <div class="script-item">
                            <el-icon class="script-drag-handle"><Rank /></el-icon>
                            <el-icon><Document /></el-icon>
                            <span class="script-name">{{ script.name }}</span>
                            <el-tag size="small" type="info">{{ script.step }}</el-tag>
                            <el-tooltip
                              v-if="script.description"
                              :content="script.description"
                              placement="top"
                            >
                              <el-icon class="info-icon"><InfoFilled /></el-icon>
                            </el-tooltip>
                            <el-button type="danger" link @click="removeScript(chapter, script)">
                              <el-icon><Delete /></el-icon>
                            </el-button>
                          </div>
                        </template>
                      </draggable>
                    </div>
                  </div>
                </template>
              </draggable>
            </el-scrollbar>
          </div>
        </div>
      </div>

      <!-- 脚本选择器对话框 -->
      <el-dialog v-model="scriptDialogVisible" title="选择脚本" width="60%" destroy-on-close>
        <div class="script-selector">
          <el-table
            ref="scriptTableRef"
            :data="availableScripts"
            height="400"
            @selection-change="handleScriptSelectionChange"
          >
            <el-table-column type="selection" width="55" />
            <el-table-column prop="name" label="脚本名称" />
            <el-table-column prop="description" label="描述" show-overflow-tooltip />
            <el-table-column prop="type" label="类型" width="100" />
            <el-table-column prop="version" label="版本" width="100" />
          </el-table>
        </div>
        <template #footer>
          <span class="dialog-footer">
            <el-button @click="scriptDialogVisible = false">取消</el-button>
            <el-button type="primary" @click="handleScriptSelect">确定</el-button>
          </span>
        </template>
      </el-dialog>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Check,
  Close,
  Plus,
  Document,
  Delete,
  Rank,
  Search,
  InfoFilled,
  Files,
  User,
  Back,
} from '@element-plus/icons-vue'
import type { FormInstance, FormRules } from 'element-plus'
import draggable from 'vuedraggable'
import { v4 as uuidv4 } from 'uuid'
import type { Workflow, WorkflowChapter, WorkflowScript, Script } from '@/api/types'
import { taskService } from '@/api/taskService'

const route = useRoute()
const router = useRouter()
const loading = ref(false)
const dragging = ref(false)
const scriptDialogVisible = ref(false)
const formRef = ref<FormInstance>()
const scriptTableRef = ref()
const scriptSearchQuery = ref('')
const activeTab = ref('scripts')
const selectRef = ref()

// 章节模板
const chapterTemplates = [
  {
    type: 'default',
    name: '默认章节',
  },
]

// 表单数据
const workflowForm = ref<Workflow>({
  id: 0,
  name: '',
  type: 1,
  label: [],
  author: '',
  description: '',
  chapters: [
    {
      cid: uuidv4(),
      name: '第一章节',
      tags: [],
    },
  ],
  updateTime: '',
})

// 可用标签
const availableTags = ref<string[]>([])

// 可用脚本列表
const availableScripts = ref<Script[]>([])
const selectedScripts = ref<Script[]>([])

// 表单校验规则
const rules: FormRules = {
  name: [{ required: true, message: '请输入工作流名称', trigger: 'blur' }],
  author: [{ required: true, message: '请输入作者', trigger: 'blur' }],
  description: [{ required: true, message: '请输入工作流描述', trigger: 'blur' }],
}

// 是否为编辑模式
const isEdit = computed(() => route.params.id !== undefined)

// 加载工作流数据
const loadWorkflow = async () => {
  if (!isEdit.value) return
  loading.value = true
  try {
    const id = parseInt(route.params.id as string)
    const workflow = await taskService.getWorkflowById(id)
    Object.assign(workflowForm.value, workflow)
    if (workflow.chapters.length === 0) {
      workflowForm.value.chapters = [
        {
          cid: uuidv4(),
          name: '第一章节',
          tags: [],
        },
      ]
    }
  } catch (err) {
    console.error('获取工作流详情失败:', err)
    ElMessage.error('获取工作流详情失败')
  } finally {
    loading.value = false
  }
}

// 加载脚本列表
const loadScripts = async () => {
  try {
    const response = await taskService.getScripts({ page: 1, page_size: 100 })
    availableScripts.value = response.items
  } catch (err) {
    console.error('获取脚本列表失败:', err)
    ElMessage.error('获取脚本列表失败')
  }
}

// 添加章节
const addChapter = () => {
  workflowForm.value.chapters.push({
    cid: uuidv4(),
    name: '新章节',
    tags: [],
  })
}

// 移除章节
const removeChapter = (index: number) => {
  workflowForm.value.chapters.splice(index, 1)
  recalculateSteps()
}

// 移除脚本
const removeScript = (chapter: WorkflowChapter, script: WorkflowScript) => {
  const index = chapter.tags.findIndex((s) => s.tid === script.tid)
  if (index > -1) {
    chapter.tags.splice(index, 1)
    recalculateSteps()
  }
}

// 打开脚本选择器
const openScriptSelector = () => {
  scriptDialogVisible.value = true
  selectedScripts.value = []
  if (scriptTableRef.value) {
    scriptTableRef.value.clearSelection()
  }
}

// 处理脚本选择变化
const handleScriptSelectionChange = (selection: Script[]) => {
  selectedScripts.value = selection
}

// 克隆章节模板
const cloneChapter = (template: { type: string; name: string }): WorkflowChapter => {
  return {
    cid: uuidv4(),
    name: '新章节',
    tags: [],
  }
}

// 重新计算指定章节中所有脚本的 step
const recalculateChapterSteps = (chapter: WorkflowChapter, chapterIndex: number) => {
  chapter.tags.forEach((script, scriptIndex) => {
    script.step = `step${chapterIndex + 1}-${scriptIndex + 1}`
  })
}

// 重新计算所有脚本的 step
const recalculateSteps = () => {
  workflowForm.value.chapters.forEach((chapter, chapterIndex) => {
    recalculateChapterSteps(chapter, chapterIndex)
  })
}

// 处理章节添加事件
const handleChapterAdd = (event: any) => {
  // 获取添加的位置
  const newIndex = event.newIndex
  // 重新计算新位置之后所有章节的脚本 step
  for (let i = newIndex; i < workflowForm.value.chapters.length; i++) {
    recalculateChapterSteps(workflowForm.value.chapters[i], i)
  }
}

// 处理脚本添加事件
const handleScriptAdd = (event: any, chapter: WorkflowChapter) => {
  // 获取添加的位置
  const newIndex = event.newIndex
  // 获取章节在工作流中的位置
  const chapterIndex = workflowForm.value.chapters.findIndex((c) => c.cid === chapter.cid)

  if (chapterIndex !== -1) {
    // 设置新添加脚本的 step
    chapter.tags[newIndex].step = `step${chapterIndex + 1}-${newIndex + 1}`
    // 重新计算当前章节中后续脚本的 step
    for (let i = newIndex + 1; i < chapter.tags.length; i++) {
      chapter.tags[i].step = `step${chapterIndex + 1}-${i + 1}`
    }
  }
}

// 处理脚本拖动结束
const handleScriptDragEnd = (event: any, chapter: WorkflowChapter) => {
  // 只有在发生了移动时才重新计算
  if (event.newIndex !== event.oldIndex) {
    // 获取章节在工作流中的位置
    const chapterIndex = workflowForm.value.chapters.findIndex((c) => c.cid === chapter.cid)
    if (chapterIndex !== -1) {
      // 重新计算当前章节中所有脚本的 step
      chapter.tags.forEach((script, index) => {
        script.step = `step${chapterIndex + 1}-${index + 1}`
      })
    }
  }
}

// 处理章节拖动结束
const handleChapterDragEnd = () => {
  dragging.value = false
  recalculateSteps()
}

// 保存工作流
const handleSave = async () => {
  if (!formRef.value) return

  try {
    await formRef.value.validate()

    if (workflowForm.value.chapters.length === 0) {
      ElMessage.warning('请添加至少一个章节')
      return
    }

    loading.value = true
    // 准备提交的数据
    let submitData: Partial<Workflow>

    if (isEdit.value) {
      // 更新时保留原有的时间字段
      const { createTime, updateTime } = await taskService.getWorkflowById(workflowForm.value.id)
      submitData = {
        ...workflowForm.value,
        type: 1,
        createTime,
        updateTime,
      }
    } else {
      // 创建时不需要 id 和时间字段
      const { id, createTime, updateTime, ...createData } = workflowForm.value
      submitData = {
        ...createData,
        type: 1,
      }
    }

    if (isEdit.value) {
      await taskService.updateWorkflow(submitData)
      ElMessage.success('更新成功')
    } else {
      await taskService.createWorkflow(submitData)
      ElMessage.success('创建成功')
    }
    router.push('/task/workflow')
  } catch (err) {
    console.error('保存工作流失败:', err)
    ElMessage.error('保存失败')
  } finally {
    loading.value = false
  }
}

// 处理脚本选择确认
const handleScriptSelect = () => {
  if (selectedScripts.value.length === 0) {
    ElMessage.warning('请选择至少一个脚本')
    return
  }

  if (workflowForm.value.chapters.length === 0) {
    ElMessage.warning('请先添加章节')
    return
  }

  // 将选中的脚本添加到最后一个章节
  const lastChapter = workflowForm.value.chapters[workflowForm.value.chapters.length - 1]
  selectedScripts.value.forEach((script) => {
    lastChapter.tags.push({
      tid: uuidv4(),
      name: script.name,
      description: script.description || '',
      status: '',
    })
  })

  // 重新计算所有脚本的 step
  recalculateSteps()

  scriptDialogVisible.value = false
}

// 克隆脚本到章节
const cloneScript = (script: Script): WorkflowScript => {
  return {
    tid: uuidv4(),
    name: script.name,
    description: script.description || '',
    status: '',
    step: '', // 会在拖放完成后通过 recalculateSteps 设置
  }
}

// 过滤可用脚本列表
const filteredScripts = computed(() => {
  if (!scriptSearchQuery.value) return availableScripts.value
  const query = scriptSearchQuery.value.toLowerCase()
  return availableScripts.value.filter(
    (script) =>
      script.name.toLowerCase().includes(query) ||
      script.description?.toLowerCase().includes(query),
  )
})

// 添加标签选择处理函数
const handleTagSelect = (value: string) => {
  // 确保不重复添加
  if (!workflowForm.value.label.includes(value)) {
    workflowForm.value.label.push(value)
  }
  // 关闭下拉框
  selectRef.value?.blur()
}

// 修改标签创建处理函数
const handleTagCreate = async (tag: string) => {
  try {
    await ElMessageBox.confirm(`确认添加新标签 "${tag}" 吗？`, '添加标签', {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'info',
    })
    // 将新标签添加到可用标签列表中
    if (!availableTags.value.includes(tag)) {
      availableTags.value.push(tag)
    }
    // 确保工作流的标签数组已初始化
    if (!workflowForm.value.label) {
      workflowForm.value.label = []
    }
    // 添加新标签到当前工作流
    if (!workflowForm.value.label.includes(tag)) {
      workflowForm.value.label.push(tag)
    }
    // 关闭下拉框
    selectRef.value?.blur()
  } catch {
    // 用户取消添加
    if (workflowForm.value.label) {
      workflowForm.value.label = workflowForm.value.label.filter((t) => t !== tag)
    }
  }
}

onMounted(() => {
  loadWorkflow()
  loadScripts()
})
</script>

<style scoped lang="scss">
.workflow-edit {
  .detail-header {
    background-color: #fff;
    padding: 16px 24px;
    border-radius: 4px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
    margin-bottom: 16px;
    display: flex;
    justify-content: space-between;
    align-items: center;

    .header-left {
      display: flex;
      align-items: center;
      gap: 8px;

      .back-button {
        padding: 8px;
        height: 32px;
        color: var(--el-text-color-regular);

        &:hover {
          color: var(--el-color-primary);
        }
      }

      .title {
        margin: 0;
        font-size: 20px;
        font-weight: 500;
        color: var(--el-text-color-primary);
        line-height: 32px;
      }
    }

    .header-right {
      display: flex;
      gap: 8px;

      :deep(.el-button) {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 4px;
        padding: 8px 16px;
        height: 32px;
        line-height: 1;

        .el-icon {
          margin: 0;
        }

        span {
          line-height: 1;
        }
      }
    }
  }

  .content-wrapper {
    padding: 24px;
    background-color: var(--el-bg-color);
    border-radius: 4px;

    .section-title {
      margin: 0 0 24px;
      padding-bottom: 16px;
      font-size: 18px;
      font-weight: 500;
      color: var(--el-text-color-primary);
      border-bottom: 1px solid var(--el-border-color-light);
    }

    .chapters-editor {
      margin-top: 24px;

      .editor-layout {
        display: flex;
        gap: 24px;

        .scripts-panel {
          width: 300px;
          background-color: var(--el-bg-color);
          border-radius: 4px;
          border: 1px solid var(--el-border-color-light);
          display: flex;
          flex-direction: column;

          .panel-header {
            padding: 16px;

            h3 {
              margin: 0 0 16px;
              font-size: 16px;
              font-weight: 500;
            }

            .component-tabs {
              :deep(.el-tabs__header) {
                margin-bottom: 12px;
              }

              .chapter-templates {
                padding: 8px 0;

                .chapter-template {
                  padding: 8px 12px;
                  background-color: var(--el-fill-color-light);
                  border-radius: 4px;
                  cursor: move;
                  margin-bottom: 8px;

                  &:last-child {
                    margin-bottom: 0;
                  }

                  &:hover {
                    background-color: var(--el-fill-color-darker);
                  }

                  .template-content {
                    display: flex;
                    align-items: center;
                    gap: 8px;
                  }
                }
              }
            }
          }

          .script-list {
            flex: 1;
            padding: 12px;
            overflow-y: auto;
            max-height: calc(100vh - 600px);

            .available-script {
              cursor: move;
              margin-bottom: 8px;
              padding: 8px 12px;
              background-color: var(--el-fill-color-light);
              border-radius: 4px;
              display: flex;
              align-items: center;
              gap: 8px;

              &:last-child {
                margin-bottom: 0;
              }

              &:hover {
                background-color: var(--el-fill-color-darker);
                transform: translateY(-1px);
              }

              .script-name {
                flex: 1;
                font-size: 14px;
              }
            }
          }
        }

        .chapters-panel {
          flex: 1;
          background-color: var(--el-fill-color-blank);
          border-radius: 4px;
          padding: 20px;
          position: relative;

          &::before {
            content: '';
            position: absolute;
            left: 30px;
            top: 0;
            bottom: 0;
            width: 2px;
            background-color: var(--el-color-primary-light-7);
            opacity: 0.5;
          }

          .panel-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 16px;
            padding: 0 24px;
          }

          .chapter-item {
            position: relative;
            margin-bottom: 24px;
            margin-left: 40px;
            margin-top: 12px;
            padding: 16px;
            background-color: var(--el-bg-color);
            border-radius: 8px;
            box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
            border: 1px solid var(--el-border-color-light);

            &::before {
              content: '';
              position: absolute;
              left: -28px;
              top: 50%;
              width: 16px;
              height: 2px;
              background-color: var(--el-color-primary-light-7);
              opacity: 0.5;
            }

            &:hover {
              border-color: var(--el-color-primary-light-5);
              box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
            }

            .chapter-number {
              position: absolute;
              top: -10px;
              left: -40px;
              width: 24px;
              height: 24px;
              background-color: var(--el-color-primary);
              color: white;
              border-radius: 12px;
              box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
              display: flex;
              align-items: center;
              justify-content: center;
              font-size: 14px;
              font-weight: 500;
              z-index: 1;
            }

            .chapter-header {
              display: flex;
              align-items: center;
              gap: 12px;
              margin-bottom: 16px;
              padding-bottom: 12px;
              background-color: var(--el-fill-color-light);
              margin: -16px -16px 16px -16px;
              padding: 16px;
              border-radius: 8px 8px 0 0;
              border-bottom: 1px solid var(--el-border-color-light);

              .chapter-drag-handle {
                cursor: move;
                color: var(--el-text-color-secondary);
              }

              .chapter-name-input {
                flex: 1;
                :deep(.el-input__wrapper) {
                  background-color: var(--el-bg-color);
                }
              }
            }

            .script-container {
              padding: 8px;
              background-color: var(--el-fill-color-blank);
              border-radius: 4px;
              min-height: 50px;
              border: 1px dashed var(--el-border-color);

              .script-item {
                margin: 8px 0;
                padding: 8px 12px;
                background-color: var(--el-bg-color);
                border-radius: 4px;
                display: flex;
                align-items: center;
                gap: 8px;
                transition: all 0.2s;
                border: 1px solid var(--el-border-color-lighter);

                &:hover {
                  transform: translateY(-1px);
                  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
                  border-color: var(--el-color-primary-light-7);
                }

                .script-drag-handle {
                  cursor: move;
                  color: var(--el-text-color-secondary);
                }

                .script-name {
                  flex: 1;
                  color: var(--el-text-color-regular);
                }

                .info-icon {
                  color: var(--el-color-info);
                  cursor: help;
                }
              }
            }
          }
        }
      }
    }
  }
}

:deep(.ghost) {
  opacity: 0.5;
  background: var(--el-color-primary-light-9);
}

.script-selector {
  :deep(.el-table) {
    margin: -12px;
  }
}

.component-tabs {
  :deep(.el-tabs__header) {
    margin-bottom: 0;
  }

  :deep(.el-tabs__content) {
    padding: 0;
  }
}

.chapter-templates {
  padding: 12px;
  overflow-y: auto;

  .chapter-template {
    cursor: move;
    margin-bottom: 8px;

    &:last-child {
      margin-bottom: 0;
    }

    &:hover {
      background-color: var(--el-fill-color-lighter);
    }
  }
}

.script-container {
  padding: 12px;
  overflow-y: auto;

  .script-item {
    cursor: move;
    margin-bottom: 8px;

    &:last-child {
      margin-bottom: 0;
    }

    &:hover {
      background-color: var(--el-fill-color-lighter);
    }
  }
}

.chapter-number {
  width: 24px;
  text-align: center;
  margin-right: 12px;
}

.script-selector {
  :deep(.el-table) {
    margin: -12px;
  }
}
</style>
